<?php

namespace Bmb\EventBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Security\Core\Util\SecureRandom;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Bmb\EventBundle\Entity\Event;
use Bmb\EventBundle\Entity\Vote;
use Bmb\EventBundle\Form\EventType;
use Bmb\EventBundle\Form\VoteType;

class EventController extends Controller {
	
	private $from = "hello@betmybirth.com";

    /**
     * Method createEventAction
     * @Security("has_role('ROLE_USER')")
     * @return type
     */
    public function createEventAction() {
        $user = $this->getUser();

        $event = new Event($user->getId());
        $event->setEvtUserId($user->getId());

        $form = $this->createForm(new EventType, $event);

        $request = $this->get('request');

        if ('POST' == $request->getMethod()) {
            $form->bind($request);

            if ($form->isValid()) {
                $em = $this->getDoctrine()->getManager();
                $event->setEvtLink($this->encryptLink($event));

                $date = \DateTime::createFromFormat("d/m/Y", $form->get('evtPlannedDate')->getData());
				if (!$date) {
					$this->get('session')->getFlashBag()->add('error', htmlspecialchars('Vérifiez le format de la date !'));
					return new RedirectResponse($this->generateUrl('bmb_event_create'));
				}
                $event->setEvtPlannedDate($date);
				
				$birthList = $event->getEvtBirthList();
				if (strpos($birthList, 'http://') === 0) {
					$event->setEvtBirthList($birthList);
				} else {
					$event->setEvtBirthList('http://' . $birthList);
				}

                $em->persist($event);
                $em->flush();

                // send admin
				$subject = "Confirmation de la création de votre événement";
				$view = "BmbEventBundle:Event:mailEventCreationConfirmation.html.twig";
				$params = array("from" => $event->getEvtTitle(), 'link' => $this->buildEventLink($event->getEvtLink()));

				$this->sendMailAction($subject, $user->getEmail(), $this->from, $view, $params);

                // redirect to avoid resubmission
                return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $event->getEvtLink())));
            } else {
                $this->get('session')->getFlashBag()->add('notice', 'Erreur : Formulaire invalide');
            }
        }

        return $this->render('BmbEventBundle:Event:create_event.html.twig', array(
                'form' => $form->createView(),
                'event' => $event
        ));
    }

    /**
     * Method manageEventAction
     * @Security("has_role('ROLE_USER')")
     * @return type
     */
    public function manageListAction() {
        $user = $this->getUser();

        $repository = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Event');

        $repositoryVotes = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Vote');

        $events = $repository->findBy(array('evtUserId' => $user->getId()), array('evtActualDate' => 'asc'));
        $eventsArray = array();

        foreach ($events as $event) {
            $votes = $repositoryVotes->findBy(array('votEvent' => $event->getId()));
            $eventArray = array('event' => $event, 'participants' => count($votes));
            array_push($eventsArray, $eventArray);
        }

        if (count($events) == 0) {
            return new RedirectResponse($this->generateUrl('bmb_event_create'));
        } elseif (count($events) == 1) { // TODO get the right event
            return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $events[0]->getEvtLink())));
        } elseif (count($events) > 1) {
            return $this->render('BmbEventBundle:Event:manage_event_list.html.twig', array('events' => $eventsArray));
        }
    }

    /**
     * Method participateEventAction
     * @return type
     */
    public function participateEventAction($eventLink) {
        $vote = new Vote();
        $form = $this->createForm(new VoteType(), $vote);
        $request = $this->get('request');

        $repositoryEvent = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Event');
        
        $event = $repositoryEvent->findOneBy(array('evtLink' => $eventLink));
		
		if ($event == null) {
			return new RedirectResponse($this->generateUrl('bmb_basics_homepage'));
		}

        $repositoryVote = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Vote');
        $votes = $repositoryVote->findBy(array('votEvent' => $event->getId()));

        $user = $this->getUser();

		if ($user != null) {
			if ($user->getId() == $event->getEvtUserId()) {
				$isAdmin = true;
			} else {
				$isAdmin = false;
			}
		} else {
			$isAdmin = false;
		}

        //$winners = $this->calcuteWinners($event, $votes);

        if ('POST' == $request->getMethod()) {
            $form->bind($request);

            if ($form->isValid()) {
                $em = $this->getDoctrine()->getManager();

                $email = $form->get('votEmail')->getData();
                if ($email == null) {
                    $vote->setVotEmail('');
                }

				$date = \DateTime::createFromFormat("d/m/Y", $form->get('votDate')->getData());
				
				if (!$date) {
					$this->get('session')->getFlashBag()->add('error', htmlspecialchars('Vérifiez le format de la date !'));
					return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $event->getEvtLink())));
				}
                $vote->setVotDate($date);

                $vote->setVotEvent($event->getId());
                $em->persist($vote);
                $em->flush();

                //$this->get('session')->getFlashBag()->add('notice', htmlspecialchars('Votre vote a bien été pris en compte'));
                $this->get('session')->getFlashBag()->add('notice_vote', htmlspecialchars('Votre vote a bien été pris en compte.'));
				
                // send admin
				$repositoryEvent = $this->getDoctrine()
					->getManager()
					->getRepository('BmbUserBundle:User');
				$admin = $repositoryEvent->find($event->getEvtUserId());
				
				$subject = "Il y a un nouveau vote pour votre événement";
				$view = "BmbEventBundle:Event:mailEventVoteInformation.html.twig";
				$params = array('voter' => $vote->getVotName(), 'link' => $this->buildEventLink($event->getEvtLink()));

				$this->sendMailAction($subject, $admin->getEmail(), $this->from, $view, $params);

                // redirect to avoid resubmission
                //return $this->render('BmbEventBundle:Event:manage_event_event.html.twig', array('event' => $event));
                return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $event->getEvtLink())));
            } else {
                $this->get('session')->getFlashBag()->add('notice', 'Erreur : Formulaire invalide');
            }
        }

        if ($event != null) {
			
			$fullLink = $this->buildEventLink($eventLink);
			$winnersArray = array();
			
			if ($event->getEvtWinner() != null) {
				$winnersArray = explode("__;__", $event->getEvtWinner());
			}
			
            return $this->render('BmbEventBundle:Event:participate_event.html.twig', array('form' => $form->createView(),
                    'event' => $event,
                    'fullLink' => $fullLink,
                    'votes' => $votes,
                    'isAdmin' => $isAdmin,
                    'winners' => $winnersArray));
        } else {
            // TODO redirect to 404 error page
        }
    }

    /**
     * Method accessEventAction
     * @return type
     */
    public function accessEventAction() {
        $eventLink = "";
        $request = $this->get('request');

        if ('POST' == $request->getMethod()) {
            $eventLink = $request->request->get('bmb_index_event_code');
        }

        if ($eventLink != "") {
            return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $eventLink)));
        } else {
            return new RedirectResponse($this->generateUrl('bmb_basics_homepage'));
        }
    }

    /**
     * Method inviteFriendsAction
     * @return type
     */
    public function inviteFriendsAction($eventLink) {
		
        $request = $this->get('request');
		$friends = $request->request->all();

        $repositoryEvent = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Event');
		
        $event = $repositoryEvent->findOneBy(array('evtLink' => $eventLink));
		
        if ('POST' == $request->getMethod()) {
			
			$subject = $event->getEvtTitle() . " vous invitent à deviner la date de naissance de leur futur bébé";
			$view = "BmbEventBundle:Event:mailInviteUser.html.twig";
			$params = array('from' => $event->getEvtTitle(), 
							'link' => $this->buildEventLink($eventLink), 
							'logo' => $this->getRequest()->getHttpHost()."/images/logo.jpg");
			
			foreach ($friends as $field => $friend) {
				if ($friend != "") {
					$this->sendMailAction($subject, $friend, $this->from, $view, $params);
				}
			}
			
			//$this->get('session')->getFlashBag()->add('notice', htmlspecialchars('Les invitations ont bien été envoyées'));
			$this->get('session')->getFlashBag()->add('notice_invite', htmlspecialchars('Les invitations ont bien été envoyées.'));
		}
		
		return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $eventLink)));
	}

    /**
     * Method editEventAction
     * @return type
     */
    public function editEventAction($eventLink) {
        $repositoryEvent = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Event');

        $event = $repositoryEvent->findOneBy(array('evtLink' => $eventLink));

        $request = $this->get('request');
		

        if ('POST' == $request->getMethod()) {
            $em = $this->getDoctrine()->getManager();

            $event->setEvtTitle($request->get('bmb_eventbundle_event_title'));
            $event->setEvtBirthList($request->get('bmb_eventbundle_event_birthlist'));

            $date = \DateTime::createFromFormat("d/m/Y", $request->get('bmb_eventbundle_event_plannedDate'));
			if (!$date) {
				$this->get('session')->getFlashBag()->add('error', htmlspecialchars('Vérifiez le format de la date !'));
				return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $event->getEvtLink())));
			}
            $event->setEvtPlannedDate($date);
				
			$birthList = $event->getEvtBirthList();
			if (strpos($birthList, 'http://') === 0) {
				$event->setEvtBirthList($birthList);
			} else {
				$event->setEvtBirthList('http://' . $birthList);
			}

            $em->flush();
			
			$this->get('session')->getFlashBag()->add('notice_edit', htmlspecialchars('L\'événement a bien été mis à jour.'));
        }

        return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $eventLink)));
    }

    /**
     * Method closeEventAction
     * @return type
     */
    public function closeEventAction($eventLink) {
        $repositoryEvent = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Event');

        $event = $repositoryEvent->findOneBy(array('evtLink' => $eventLink));

        $repositoryVote = $this->getDoctrine()
            ->getManager()
            ->getRepository('BmbEventBundle:Vote');
        $votes = $repositoryVote->findBy(array('votEvent' => $event->getId()));

        $request = $this->get('request');
		

        if ('POST' == $request->getMethod()) {
            $em = $this->getDoctrine()->getManager();

            $event->setEvtName($request->get('bmb_eventbundle_event_name'));
            $event->setEvtGender($request->get('bmb_eventbundle_event_gender'));
            $event->setEvtActualWeight($request->get('bmb_eventbundle_event_weight'));
            $event->setEvtActualSize($request->get('bmb_eventbundle_event_size'));

            $date = \DateTime::createFromFormat("d/m/Y", $request->get('bmb_eventbundle_event_birthDate'));
			if (!$date) {
				$this->get('session')->getFlashBag()->add('error', htmlspecialchars('Vérifiez le format de la date !'));
				return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $event->getEvtLink())));
			}
            $event->setEvtActualDate($date);
			
			$winnersIds = $this->calcuteWinners($event, $votes);

			$winnersField = "";
			$count = 0;
			
			foreach ($winnersIds as $winnerId) {
				
				$winningVote = $repositoryVote->find($winnerId);
				if ($count == 0) {
					$winnersField = $winningVote->getVotName();
				} else {
					$winnersField = $winnersField  . "__;__" . $winningVote->getVotName();
				}
				$count++;
				
				if ($winningVote->getVotEmail() != null && $winningVote->getVotEmail() != "") {
					
					$subject = "Félicitations, vous avez trouvé la date de naissance de " . $request->get('bmb_eventbundle_event_name');
					$view = "BmbEventBundle:Event:mailEventClosingWinner.html.twig";
					$params = array('link' => $this->buildEventLink($eventLink), 'name' => $request->get('bmb_eventbundle_event_name'));
					
					$this->sendMailAction($subject, $winningVote->getVotEmail(), $this->from, $view, $params);
				}
			}
			
			$event->setEvtWinner($winnersField);
			
			// persist event modification
			$em->flush();
					
			$subject = "Confirmation de la fermeture de l'événement";
			$view = "BmbEventBundle:Event:mailEventClosingConfirmation.html.twig";
			$params = array('link' => $this->buildEventLink($eventLink), 
							'logo' => $this->getRequest()->getHttpHost()."/images/logo.jpg");
			
			$this->sendMailAction($subject, $this->getUser()->getEmail(), $this->from, $view, $params);
        }

        return new RedirectResponse($this->generateUrl('bmb_event_participate', array('eventLink' => $eventLink)));
    }

    /**
     * Send messages to many users
     * @param Message $message
     */
    public function sendMailsAction($subject, $to, $from, $view, $params) {
		
		if ($to instanceof String) {
			$this->sendMailAction($subject, $to, $from, $view, $params);
		} else {
			foreach ($to as $user) {
				$this->sendMailAction($subject, $user, $from, $view, $params);
			}
		}
    }

    /**
     * Send a message to the administrator
     * @param Message $message
     */
    public function sendMailAction($subject, $to, $from, $view, $params) {
        //$view = 'BmbEventBundle:Event:mailInviteUser.html.twig';

        // mail composition
        $mail = \Swift_Message::newInstance()
            //->setSubject($from . ' vous invite à parier sur une date de naissance !')
            ->setSubject($subject)
            ->setFrom($from)
            ->setTo($to)
            //->setBody($this->renderView($view, array('from' => $from, 'link' => $link)), 'text/html');
            ->setBody($this->renderView($view, $params), 'text/html');

        // send the mail
        try {
			$this->get('mailer')->send($mail);
//            if (!$this->get('mailer')->send($mail)) {
//				$this->get('session')->getFlashBag()->add('error', 'Erreur d\'envoi');
//			}
        } catch (Swift_TransportException $e) {
            throw new \Swift_TransportException;
        }
    }

    /**
     * Encrypt event link
     * @param \Bmb\EventBundle\Entity\Event $event
     * @return String
     */
    public function buildEventLink($link) {

        return $this->getRequest()->getHttpHost() . $this->generateUrl('bmb_event_participate', array('eventLink' => $link)) . "#event";
    }

    /**
     * Encrypt event link
     * @param \Bmb\EventBundle\Entity\Event $event
     * @return String
     */
    public function encryptLink(Event $event) {
        
        $generator = new SecureRandom();
        $url = $event->getId() . '_' . $event->getEvtTitle() . '_' . $event->getEvtUserId() . '_' . $generator->nextBytes(5);

        return md5($url);
    }
	
//	public function calcuteWinners($event, $votes) {
//		
//		$winners = array();
//		
//        if ($event->getEvtActualDate() != null) {
//            foreach ($votes as $vote) {
//                if ($vote->getVotDate()->format('Ymd') == $event->getEvtActualDate()->format('Ymd')) {
//                    array_push($winners, $vote);
//                }
//            }
//        }
//		
//		return $winners;
//	}
	
	public function calcuteWinners($event, $votes) {
		
		$betters = array();
		$winnerIds = array();
		
        if ($event->getEvtActualDate() != null) {
            foreach ($votes as $vote) {
				$points = 0;
				
                if ($vote->getVotDate()->format('Ymd') == $event->getEvtActualDate()->format('Ymd')) {
					$points++;
                }
				
                if ($vote->getVotGender() == $event->getEvtGender()) {
					$points++;
                }
				
                if ($vote->getVotWeight() == $event->getEvtActualWeight()) {
					$points++;
                }
				
                if ($vote->getVotSize() == $event->getEvtActualSize()) {
					$points++;
                }
				
				$betters[$vote->getId()] = $points;
            }
        }
		
		if (max($betters) != 0) {
			$winnerIds = array_keys($betters, max($betters));
		}
		
		
		return $winnerIds;
	}

}
